<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="org.slf4j.LoggerFactory"%>
<%@page import="org.slf4j.Logger"%>
<%@page import="java.io.Writer" %>
<%@page import="java.io.IOException" %>
<%@page import="javax.naming.*" %>
<%@page import="java.net.URLEncoder" %>
<%@page contentType="text/html;charset=UTF-8" language="java" %>
<%!	
	private static final String SPACE = " ";
	private static final int MAX_DEPTH = 50;
	Logger logger = LoggerFactory.getLogger("jndibrowser.jsp");

	private String getIdentStr(int indent) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < indent; i++) {
			sb.append(SPACE);
		}
		return sb.toString();
	}

	private void listContext(Context ctx, int indent, Writer out, HttpServletRequest req, String parentPath) throws NamingException, IOException {
		NamingEnumeration list = null;
		List<Binding> items = new ArrayList<Binding>();
		try {
			list = ctx.listBindings("");
		} catch (NamingException e) {
			out.write(indent + "ERROR, unable to list bindings : " + e + "\n");
		}
		while (list != null && list.hasMore()) {
			try {
				Binding item = (Binding) list.next();
				String name = item.getName();
				if (name.indexOf("!") != -1) items.add(0, item);
				else items.add(item);								 
			} catch (Exception e) {
				out.write(indent + "ERROR : " + e + "\n");
			}
		}
		for(Binding item : items) {
			String className = item.getClassName();
			String name = item.getName();
			String s = parentPath.equals("") ? parentPath : parentPath + "/";
			String linkHref = req.getContextPath() + "/jndibrowser.jsp?startAt=" + s + URLEncoder.encode(name, "utf-8");
			out.write(getIdentStr(indent));
			if (s.startsWith("java:global") || name.equals("java:global")) {
				out.write("<b>");
				out.write("<a href=\"");
				out.write(linkHref);
				out.write("\">");
				out.write(s+name + " (" + className + ")\n");
				out.write("</a>");
				out.write("</b>");
			}
			Object o = item.getObject();
			if (o instanceof javax.naming.Context && indent < MAX_DEPTH) {
				listContext((Context) o, indent + 1, out, req, s + name);
			}
		}
	}
%>
<%
	String startAt = request.getParameter("startAt");
	String startAtRepop = startAt == null ? "" : startAt;
	Context startCtx = new InitialContext();
	Object boundObject = null;
	if (startAt != null) {
		// perform lookup
		if (!startAt.equals("")) {
			Object lookedUp = startCtx.lookup(startAt);
			if (lookedUp instanceof Context) {
				startCtx = (Context) lookedUp;
			} else {
				boundObject = lookedUp;
			}
		}
	} else {
		startCtx = null;
	}
%>
<html>
	<head><title>JNDI Browser</title></head>
	<body>
		<h1>JNDI Tree</h1>
		<p>
		<form action="${pageContext.request.contextPath}/jndibrowser.jsp" method="GET">
			Lookup : <input type="text" name="startAt" size="80" value="<%=startAtRepop%>"/>
			<input type="submit"/>
		</form>
	</p>
	<%
		if (boundObject != null) {
			// show object info
%>
	<p>Looked up "<%=startAt%>" : <%=boundObject%></p>
	<%
	} else if (startCtx != null) {
		// show tree
%>
	<pre><%listContext(startCtx, 0, out, request, startAt);%></pre>
	<%
	}
	%>  
</body>
</html>